#import "ZLTextLayout.h"

@interface ZLTextLayout ()

@property (nonatomic, strong) NSTextStorage *textStorage;


@property (nonatomic, strong, readwrite) ZLTextHighlight *highlightRange;

@end

@implementation ZLTextLayout

#pragma mark - Initialization

- (instancetype)initWithText:(NSAttributedString *)text size:(CGSize)size {
    self = [super init];
    if (self) {
        _highlights = [NSMutableArray array];
        [self setupTextKitComponentsWithText:text size:size];
    }
    return self;
}

- (void)setupTextKitComponentsWithText:(NSAttributedString *)text size:(CGSize)size {
    // 创建文本容器
    _textContainer = [[NSTextContainer alloc] initWithSize:size];
    _textContainer.lineFragmentPadding = 0;
    
    // 创建布局管理器
    _layoutManager = [[NSLayoutManager alloc] init];
    [_layoutManager addTextContainer:_textContainer];
    
    // 创建文本存储
    _textStorage = [[NSTextStorage alloc] initWithAttributedString:text];
    [_textStorage addLayoutManager:_layoutManager];
    
    NSLog(@"文本布局初始化完成，文本长度: %lu", (unsigned long)text.length);
}

#pragma mark - Public Methods

- (void)addHighlight:(ZLTextHighlight *)highlight {
    if (!highlight || highlight.range.location == NSNotFound) return;
    
    @try {
        // 验证范围是否有效
        if (NSMaxRange(highlight.range) <= self.textStorage.length) {
            [self.highlights addObject:highlight];
            [self applyHighlight:highlight];
            NSLog(@"添加高亮文本成功，范围: %@, tapAction: %@", NSStringFromRange(highlight.range), highlight.tapAction ? @"存在" : @"不存在");
        } else {
            NSLog(@"高亮范围无效: %@", NSStringFromRange(highlight.range));
        }
    } @catch (NSException *exception) {
        NSLog(@"添加高亮文本异常: %@", exception);
    }
}

- (void)removeHighlight:(ZLTextHighlight *)highlight {
    if (!highlight) return;
    
    @try {
        [self.highlights removeObject:highlight];
        [self removeHighlightAttributes:highlight];
        if (self.highlightRange == highlight) {
            self.highlightRange = nil;
        }
        NSLog(@"移除高亮文本成功，范围: %@", NSStringFromRange(highlight.range));
    } @catch (NSException *exception) {
        NSLog(@"移除高亮文本异常: %@", exception);
    }
}

- (void)removeAllHighlights {
    @try {
        for (ZLTextHighlight *highlight in self.highlights) {
            [self removeHighlightAttributes:highlight];
        }
        [self.highlights removeAllObjects];
        self.highlightRange = nil;
        NSLog(@"移除所有高亮文本成功");
    } @catch (NSException *exception) {
        NSLog(@"移除所有高亮文本异常: %@", exception);
    }
}

- (void)touchPoint:(CGPoint)point {
    NSLog(@"开始检测点击位置: %@", NSStringFromCGPoint(point));
    
    // 打印文本容器的信息
    NSLog(@"文本容器大小: %@", NSStringFromCGSize(self.textContainer.size));
    
    // 获取点击位置的字符索引
    CGFloat fractionOfDistance = 0;
    NSUInteger characterIndex = [self.layoutManager characterIndexForPoint:point
                                                         inTextContainer:self.textContainer
                                fractionOfDistanceBetweenInsertionPoints:&fractionOfDistance];
    
    NSLog(@"点击位置对应的字符索引: %lu, 距离比例: %f", (unsigned long)characterIndex, fractionOfDistance);
    
    // 打印文本内容
    NSLog(@"当前文本内容: %@", self.textStorage.string);
    
    // 检查是否点击了高亮文本
    for (ZLTextHighlight *highlight in self.highlights) {
        NSString *highlightText = [self.textStorage.string substringWithRange:highlight.range];
        NSLog(@"检查高亮文本: %@, 范围: %@", highlightText, NSStringFromRange(highlight.range));
        
        if (NSLocationInRange(characterIndex, highlight.range)) {
            NSLog(@"找到匹配的高亮文本，范围: %@", NSStringFromRange(highlight.range));
            
            // 检查点击位置是否在文本的边界框内
            NSRange glyphRange = [self.layoutManager glyphRangeForCharacterRange:highlight.range
                                                           actualCharacterRange:NULL];
            CGRect boundingRect = [self.layoutManager boundingRectForGlyphRange:glyphRange
                                                               inTextContainer:self.textContainer];
            
            NSLog(@"高亮文本边界框: %@", NSStringFromCGRect(boundingRect));
            
            // 转换点击坐标到文本容器的坐标系统
            CGPoint convertedPoint = CGPointMake(point.x - boundingRect.origin.x,
                                               point.y - boundingRect.origin.y);
            NSLog(@"转换后的点击坐标: %@", NSStringFromCGPoint(convertedPoint));
            
            if (CGRectContainsPoint(boundingRect, point)) {
                NSLog(@"点击位置在高亮文本边界框内");
                
                // 执行点击回调
                if (highlight.tapAction) {
                    NSLog(@"执行点击回调");
                    dispatch_async(dispatch_get_main_queue(), ^{
                        highlight.tapAction();
                    });
                } else {
                    NSLog(@"高亮文本没有设置点击回调");
                }
                return;
            } else {
                NSLog(@"点击位置不在高亮文本边界框内");
            }
        }
    }
    
    NSLog(@"没有找到匹配的高亮文本");
}

- (CGSize)textBoundingSize {
    NSRange glyphRange = [self.layoutManager glyphRangeForTextContainer:self.textContainer];
    return [self.layoutManager boundingRectForGlyphRange:glyphRange
                                       inTextContainer:self.textContainer].size;
}

- (void)drawInContext:(CGContextRef)context {
    if (!context) return;
    
    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
    NSRange glyphRange = [self.layoutManager glyphRangeForTextContainer:self.textContainer];
    
    [self.layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:bounds.origin];
    [self.layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:bounds.origin];
}

#pragma mark - Private Methods

- (void)applyHighlight:(ZLTextHighlight *)highlight {
    if (!highlight) return;
    
    @try {
        // 设置正常状态的颜色
        [self.textStorage addAttribute:NSForegroundColorAttributeName
                               value:highlight.normalColor
                               range:highlight.range];
        
        // 设置下划线
        if (highlight.showUnderline) {
            [self.textStorage addAttribute:NSUnderlineStyleAttributeName
                                   value:@(NSUnderlineStyleSingle)
                                   range:highlight.range];
        }
        NSLog(@"应用高亮属性成功");
    } @catch (NSException *exception) {
        NSLog(@"应用高亮属性异常: %@", exception);
    }
}

- (void)removeHighlightAttributes:(ZLTextHighlight *)highlight {
    if (!highlight) return;
    
    @try {
        [self.textStorage removeAttribute:NSForegroundColorAttributeName range:highlight.range];
        [self.textStorage removeAttribute:NSUnderlineStyleAttributeName range:highlight.range];
        NSLog(@"移除高亮属性成功");
    } @catch (NSException *exception) {
        NSLog(@"移除高亮属性异常: %@", exception);
    }
}

- (void)applyHighlightState:(BOOL)highlighted toHighlight:(ZLTextHighlight *)highlight {
    if (!highlight) return;
    
    @try {
        UIColor *color = highlighted ? highlight.highlightColor : highlight.normalColor;
        [self.textStorage addAttribute:NSForegroundColorAttributeName
                               value:color
                               range:highlight.range];
        NSLog(@"应用高亮状态成功: %@", highlighted ? @"高亮" : @"正常");
    } @catch (NSException *exception) {
        NSLog(@"应用高亮状态异常: %@", exception);
    }
}

- (void)clearCurrentHighlight {
    if (self.highlightRange) {
        [self applyHighlightState:NO toHighlight:self.highlightRange];
        self.highlightRange = nil;
        NSLog(@"清除当前高亮状态");
    }
}

- (ZLTextHighlight *)highlightAtIndex:(NSUInteger)index {
    for (ZLTextHighlight *highlight in self.highlights) {
        if (NSLocationInRange(index, highlight.range)) {
            return highlight;
        }
    }
    return nil;
}

- (void)setSize:(CGSize)size {
    _size = size;
    self.textContainer.size = size;
}

@end 
